; Project name	:	XTIDE Universal BIOS
; Description	:	Equates for 8237 DMA Controllers.

;
; XTIDE Universal BIOS and Associated Tools
; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
;

%ifndef DMA_CONTROLLER_INC
%define DMA_CONTROLLER_INC

; 8237 Master (8-bit) and Slave (16-bit) DMA Controller Ports

; Page Registers
PAGE_DMA8_CH_1		EQU		83h
PAGE_DMA8_CH_2		EQU		81h
PAGE_DMA8_CH_3		EQU		82h
PAGE_DMA16_CH_5		EQU		8Bh		; AT+
PAGE_DMA16_CH_6		EQU		89h		; AT+
PAGE_DMA16_CH_7		EQU		8Ah		; AT+

; Base and Current Address Registers
BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH1_out	EQU		02h
BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH2_out	EQU		04h
BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out	EQU		06h
BASE_AND_CURRENT_ADDRESS_REGISTER_DMA16_CH5_out	EQU		0C4h	; AT+
BASE_AND_CURRENT_ADDRESS_REGISTER_DMA16_CH6_out	EQU		0C8h	; AT+
BASE_AND_CURRENT_ADDRESS_REGISTER_DMA16_CH7_out	EQU		0CCh	; AT+
CURRENT_ADDRESS_REGISTER_DMA8_CH1_in			EQU		02h
CURRENT_ADDRESS_REGISTER_DMA8_CH2_in			EQU		04h
CURRENT_ADDRESS_REGISTER_DMA8_CH3_in			EQU		06h
CURRENT_ADDRESS_REGISTER_DMA16_CH5_in			EQU		0C4h	; AT+
CURRENT_ADDRESS_REGISTER_DMA16_CH6_in			EQU		0C8h	; AT+
CURRENT_ADDRESS_REGISTER_DMA16_CH7_in			EQU		0CCh	; AT+

; Base and Current Count Registers
BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH1_out	EQU		03h
BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH2_out	EQU		05h
BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out	EQU		07h
BASE_AND_CURRENT_COUNT_REGISTER_DMA16_CH5_out	EQU		0C6h	; AT+
BASE_AND_CURRENT_COUNT_REGISTER_DMA16_CH6_out	EQU		0CAh	; AT+
BASE_AND_CURRENT_COUNT_REGISTER_DMA16_CH7_out	EQU		0CEh	; AT+
CURRENT_COUNT_REGISTER_DMA8_CH1_in				EQU		03h
CURRENT_COUNT_REGISTER_DMA8_CH2_in				EQU		05h
CURRENT_COUNT_REGISTER_DMA8_CH3_in				EQU		07h
CURRENT_COUNT_REGISTER_DMA16_CH5_in				EQU		0C6h	; AT+
CURRENT_COUNT_REGISTER_DMA16_CH6_in				EQU		0CAh	; AT+
CURRENT_COUNT_REGISTER_DMA16_CH7_in				EQU		0CEh	; AT+

; Command Registers (Command Value used by PCs is 0)
COMMAND_REGISTER_DMA8_out		EQU		08h
COMMAND_REGISTER_DMA16_out		EQU		0D0h	; AT+
	MEM_TO_MEM_XFERS_DISABLE	EQU		0
	MEM_TO_MEM_XFERS_ENABLE		EQU		(1<<0)

	CH0_ADDRESS_HOLD_DISABLE	EQU		0
	CH0_ADDRESS_HOLD_ENABLE		EQU		(1<<1)	; When MEM_TO_MEM_XFERS_ENABLE

	CONTROLLER_ENABLE			EQU		0
	CONTROLLER_DISABLE			EQU		(1<<2)	; Instead of Controller Enable

	NORMAL_TIMING				EQU		0
	COMPRESSED_TIMING			EQU		(1<<3)	; Instead of Normal Timing when MEM_TO_MEM_XFERS_DISABLE

	FIXED_PRIORITY				EQU		0
	ROTATING_PRIORITY			EQU		(1<<4)	; Instead of Fixed Priority

	LATE_WRITE_SELECTION		EQU		0
	EXTENDED_WRITE_SELECTION	EQU		(1<<5)	; Instead of Late Write Selection

	DREQ_SENSE_ACTIVE_HIGH		EQU		0
	DREQ_SENSE_ACTIVE_LOW		EQU		(1<<6)	; Instead of DREQ Sense Active High

	DACK_SENSE_ACTIVE_LOW		EQU		0
	DACK_SENSE_ACTIVE_HIGH		EQU		(1<<7)	; Instead of DACK Sense Active Low


; Status Registers (reading will clear Terminal Count flags)
STATUS_REGISTER_DMA8_in			EQU		COMMAND_REGISTER_DMA8_out
	FLG_CH1_HAS_REACHED_TERMINAL_COUNT		EQU		(1<<1)
	FLG_CH2_HAS_REACHED_TERMINAL_COUNT		EQU		(1<<2)
	FLG_CH3_HAS_REACHED_TERMINAL_COUNT		EQU		(1<<3)
	FLG_CH1_REQUEST							EQU		(1<<5)
	FLG_CH2_REQUEST							EQU		(1<<6)
	FLG_CH3_REQUEST							EQU		(1<<7)
STATUS_REGISTER_DMA16_in		EQU		COMMAND_REGISTER_DMA16_out	; AT+
	FLG_CH5_HAS_REACHED_TERMINAL_COUNT		EQU		(1<<1)
	FLG_CH6_HAS_REACHED_TERMINAL_COUNT		EQU		(1<<2)
	FLG_CH7_HAS_REACHED_TERMINAL_COUNT		EQU		(1<<3)
	FLG_CH5_REQUEST							EQU		(1<<5)
	FLG_CH6_REQUEST							EQU		(1<<6)
	FLG_CH7_REQUEST							EQU		(1<<7)


; Request Registers (Software DMA Request)
REQUEST_REGISTER_DMA8_out		EQU		09h
	FLG_SET_REQUEST		EQU		(1<<2)
	CLEAR_CH1_REQUEST	EQU		CHANNEL_1
	CLEAR_CH2_REQUEST	EQU		CHANNEL_2
	CLEAR_CH3_REQUEST	EQU		CHANNEL_3
	SET_CH1_REQUEST		EQU		(CHANNEL_1 | FLG_SET_REQUEST)
	SET_CH2_REQUEST		EQU		(CHANNEL_2 | FLG_SET_REQUEST)
	SET_CH3_REQUEST		EQU		(CHANNEL_3 | FLG_SET_REQUEST)
REQUEST_REGISTER_DMA16_out		EQU		0D2h	; AT+
	CLEAR_CH5_REQUEST	EQU		CLEAR_CH1_REQUEST
	CLEAR_CH6_REQUEST	EQU		CLEAR_CH2_REQUEST
	CLEAR_CH7_REQUEST	EQU		CLEAR_CH3_REQUEST
	SET_CH5_REQUEST		EQU		SET_CH1_REQUEST
	SET_CH6_REQUEST		EQU		SET_CH2_REQUEST
	SET_CH7_REQUEST		EQU		SET_CH3_REQUEST


; Mask Registers (setting a mask bit disables DMA channel)
MASK_REGISTER_DMA8_out			EQU		0Ah
	FLG_SET_MASK		EQU		FLG_SET_REQUEST
	CLEAR_CH1_MASK_BIT	EQU		CLEAR_CH1_REQUEST
	CLEAR_CH2_MASK_BIT	EQU		CLEAR_CH2_REQUEST
	CLEAR_CH3_MASK_BIT	EQU		CLEAR_CH3_REQUEST
	SET_CH1_MASK_BIT	EQU		SET_CH1_REQUEST
	SET_CH2_MASK_BIT	EQU		SET_CH2_REQUEST
	SET_CH3_MASK_BIT	EQU		SET_CH3_REQUEST
MASK_REGISTER_DMA16_out			EQU		0D4h	; AT+
	CLEAR_CH5_MASK_BIT	EQU		CLEAR_CH5_REQUEST
	CLEAR_CH6_MASK_BIT	EQU		CLEAR_CH6_REQUEST
	CLEAR_CH7_MASK_BIT	EQU		CLEAR_CH7_REQUEST
	SET_CH5_MASK_BIT	EQU		SET_CH5_REQUEST
	SET_CH6_MASK_BIT	EQU		SET_CH6_REQUEST
	SET_CH7_MASK_BIT	EQU		SET_CH7_REQUEST


; Mode Registers
MODE_REGISTER_DMA8_out			EQU		0Bh
	; Select channel number (bits 0...1)
	CHANNEL_1			EQU		1
	CHANNEL_2			EQU		2
	CHANNEL_3			EQU		3
MODE_REGISTER_DMA16_out			EQU		0D6h	; AT+
	CHANNEL_5			EQU		CHANNEL_1
	CHANNEL_6			EQU		CHANNEL_2
	CHANNEL_7			EQU		CHANNEL_3
	; Transfer type (bits 2...3)
	VERIFY				EQU		(0<<2)
	WRITE				EQU		(1<<2)	; To memory
	READ				EQU		(2<<2)	; From memory
	; Autoinitialization enable/disable (bit 4)
	AUTOINIT_DISABLE	EQU		0
	AUTOINIT_ENABLE		EQU		(1<<4)	; Instead of autoinitialization disable
	; Address increment/decrement select (bit 5)
	ADDRESS_INCREMENT	EQU		0
	ADDRESS_DECREMENT	EQU		(1<<5)	; Instead of address increment
	; Mode type selection (bits 6...7)
	DEMAND_MODE			EQU		(0<<6)
	SINGLE_MODE			EQU		(1<<6)
	BLOCK_MODE			EQU		(2<<6)
	CASCADE_MODE		EQU		(3<<6)


; Clear Byte Flip-Flops (any byte resets low/high byte flip-flop to low)
CLEAR_FLIPFLOP_DMA8_out			EQU		0Ch
CLEAR_FLIPFLOP_DMA16_out		EQU		0D8h	; AT+


; Temporary Registers
TEMP_REGISTER_DMA8_in			EQU		0Dh
TEMP_REGISTER_DMA16_in			EQU		0DAh	; AT+


; Master Clear (any byte does the same as hardware reset)
MASTER_CLEAR_DMA8_out			EQU		TEMP_REGISTER_DMA8_in
MASTER_CLEAR_DMA16_out			EQU		TEMP_REGISTER_DMA16_in	; AT+


; Clear all mask bits (any byte enables all DMA channels)
CLEAR_ALL_MASK_BITS_DMA8_out	EQU		0Eh
CLEAR_ALL_MASK_BITS_DMA16_out	EQU		0DCh	; AT+


; Write All Mask Bits
WRITE_ALL_MASK_BITS_DMA8_out	EQU		0Fh
	ALL_MASK_BITS_SET_CH0		EQU		(1<<0)
	ALL_MASK_BITS_SET_CH1		EQU		(1<<CHANNEL_1)
	ALL_MASK_BITS_SET_CH2		EQU		(1<<CHANNEL_2)
	ALL_MASK_BITS_SET_CH3		EQU		(1<<CHANNEL_3)
WRITE_ALL_MASK_BITS_DMA16_out	EQU		0DEh	; AT+
	ALL_MASK_BITS_SET_CH4		EQU		ALL_MASK_BITS_SET_CH0
	ALL_MASK_BITS_SET_CH5		EQU		(1<<CHANNEL_5)
	ALL_MASK_BITS_SET_CH6		EQU		(1<<CHANNEL_6)
	ALL_MASK_BITS_SET_CH7		EQU		(1<<CHANNEL_7)


%endif ; DMA_CONTROLLER_INC
